package lambdaInterface;

import java.nio.file.DirectoryStream;
import java.util.function.*;

/**
 * @author 阿聪
 * @version 1.0
 * @date 2019/8/15 下午 3:32
 */
public class demo {
    /**
     * 该类型的接口被称为 函数式接口
     * 注解FunctionalInterface加不加都可以.等同于重写的方法加不加重写注解一样.仅仅是做为标识而已
     * @param <T> 形参类型
     */
    @FunctionalInterface
    interface DiyLambdaInterface<T> {
        int aa(T t);
    }

    public static void main(String[] args) {

        // Lambda 称为 函数描述符
        // 比如 String::toString
        // 比如 (String s) -> s.toString()
        // 比如 (String s) -> {return s.toString()}

        // 接受函数描述符的引用类型接口都称为 函数式接口
        // 结构: 函数式接口 变量名 = 函数描述符
        // 比如 Function<String,String> functionObj = String::toString , Function被称为 函数式接口
        // 函数式接口可以作为方法形参,来丰富方法.很像是js的回调函数.

        // Predicate[谓语] 泛型指的是形参类型.返回值固定为布尔类型.场景:布尔表达式.
        // Predicate<T> 接受 T -> R
        Predicate<String> predicate = String::isEmpty;
        boolean predicateResult = predicate.test("");
        System.out.println(predicateResult);
        predicateResult = predicate.test("the is Predicate test");
        System.out.println(predicateResult);

        // Consumer[消费者] 泛型指的是形参类型.返回值为void.单纯是执行代码用的.场景:消费对象.
        // Consumer<T> 接受 T -> void
        Consumer<String> consumerObj = System.out::println;
        consumerObj.accept("the is Consumer test");

        // Supplier[供应商] 泛型指的是返回值类型.没有形参.场景:创建对象.
        // Supplier<T> 接受 () -> T
        Supplier<String> supplierObj = () -> "the is Supplier test";
        String supplierResult = supplierObj.get();
        System.out.println(supplierResult);

        // Function[方法/函数] 两个泛型分别定义形参类型和返回类型.场景:选择/提取,回调函数等.
        // Function<T, U> 接受 T -> U
        Function<String,String> functionObj = String::toString;
        String functionResult = functionObj.apply("the is Function test");
        System.out.println(functionResult);

        // UnaryOperator[一元运算符] 泛型指的是形参类型和返回类型.形参类型和返回值类型相同.场景:进行运算后把运算结果返回.
        // UnaryOperator<T> 接受 T -> T
        UnaryOperator<String> unaryOperatorObj = String::toString;
        String unaryOperatorResult = unaryOperatorObj.apply("the is UnaryOperator test");
        System.out.println(unaryOperatorResult);

        // 以上的函数式接口类名加上[Bi]之后,形参数量都+1,也就是多个一个形参泛型.Supplier[供应商]除外,因为他只是为了创建对象而存在的.
        // BiFunction<T, U, R> 接受 (T, U) -> R
        BiFunction<String,String,String> biFunctionObj = (s,s1) -> s+s1;
        String biFunctionResult = biFunctionObj.apply("the is BiFunction test",",the is BiFunction2 test");
        System.out.println(biFunctionResult);

        // BinaryOperator[二元运算符] 泛型指的是形参类型和返回类型.形参类型和返回值类型相同.场景:进行运算后把运算结果返回.
        // BinaryOperator<T, T> 接受 T,T -> T
        // 因为BinaryOperator继承了BiFunction,所以和BiFunction很像.但不同的是前者的两个形参类型和返回值类型都是一样的.
        BinaryOperator<String> binaryOperatorObj = (s,s1) -> s+s1;
        String binaryOperatorResult = binaryOperatorObj.apply("the is BinaryOperator test", "the is BinaryOperator test");
        System.out.println(binaryOperatorResult);

        // 自定义接口,用于接收"lambda值"的.
        // DiyLambdaInterface<T> 接受 T -> int
        DiyLambdaInterface<String> diyLambdaInterface = String::length;
        int diyLambdaInterfaceResult = diyLambdaInterface.aa("the is diyLambdaInterface test ");
        System.out.println(diyLambdaInterfaceResult);


    }
}
